import { goodList } from './data.js'

class Goods {
    constructor(originGoodsItem) {
        const tempGoodsItem = { ...originGoodsItem };
        Object.freeze(tempGoodsItem);
        Object.defineProperty(this, 'goodsItem', {
            get() {
                return tempGoodsItem;
            },
            set(val) {
                throw new Error(`您希望将goodsItem设置为${val},但它是只读属性,不可更改!`);
            },
            configurable: false
        })

        let tempChooseNum = 0;
        Object.defineProperty(this, 'chooseNum', {
            get() {
                return tempChooseNum;
            },
            set(val) {
                if(typeof val !== 'number') throw new Error(`您希望将chooseNum设置为${val},但其值需要的类型为number!`);
                if(parseInt(val) !== val) throw new Error(`您希望将chooseNum设置为${val},但其值只能是整数!`);
                if(val < 0) throw new Error(`您希望将chooseNum设置为${val},但其值只能大于等于0!`);
                tempChooseNum = val;
            },
            configurable: false
        })
        // Object.freeze(this);
    }
    get totalPrice() {
        return this.goodsItem.price * this.chooseNum;
    }
    get isChoose() {
        return this.chooseNum > 0;
    }
    increase() {
        this.chooseNum++;
    }
    decrease() {
        if(this.chooseNum == 0) return 0;
        this.chooseNum--;
    }
}
Object.freeze(Goods.prototype);

class BuyCar {
    constructor() {
        const tempUiGoodsList = goodList.map(item => new Goods(item));
        Object.defineProperty(this, 'uiGoodsList', {
            get() {
                return tempUiGoodsList;
            },
            set(val) {
                throw new Error(`您希望将uiGoodsList设置为${val},但它是只读属性,不可更改!`);
            },
            configurable: false
        })

        let tempDeliveryFee = 2;
        Object.defineProperty(this, 'deliveryFee', {
            get() {
                return tempDeliveryFee;
            },
            set(val) {
                if(typeof val !== 'number') throw new Error(`您希望将chooseNum设置为${val},但其值需要的类型为number!`);
                if(val < 0) throw new Error(`您希望将chooseNum设置为${val},但其值只能大于等于0!`);
                tempDeliveryFee = val;
            },
            configurable: false
        })

        let tempDeliveryThreshold = 30;
        Object.defineProperty(this, 'deliveryThreshold', {
            get() {
                return tempDeliveryThreshold;
            },
            set(val) {
                if(typeof val !== 'number') throw new Error(`您希望将deliveryThreshold设置为${val},但其值需要的类型为number!`);
                if(val < 0) throw new Error(`您希望将deliveryThreshold设置为${val},但其值只能大于等于0!`);
                tempDeliveryThreshold = val;
            },
            configurable: false
        })
    }
    get totalPrice() {
        return (this.uiGoodsList.reduce((sum, item) => sum += item.goodsItem.price * item.chooseNum, 0)).toFixed(2);
    }
    get deliveryThresholdDifference() {
        const totalPrice = this.totalPrice;
        if(totalPrice >= this.deliveryThreshold) return 0;
        return Math.round(this.deliveryThreshold - totalPrice);
    }
    get chooseNum() {
        return this.uiGoodsList.reduce((sum, item) => item.chooseNum > 0 ? sum += item.chooseNum : sum, 0);
    }
    increase(index) {
        this.uiGoodsList[index].increase();
    }
    decrease(index) {
        this.uiGoodsList[index].decrease();
    }
    isChoose(index) {
        return this.uiGoodsList[index].isChoose;
    }
}
Object.freeze(BuyCar.prototype);

class Ui {
    constructor() {
        const tempBuyCar = new BuyCar();
        Object.freeze(tempBuyCar);
        Object.defineProperty(this, 'buyCar', {
            get() {
                return tempBuyCar;
            },
            set(val) {
                throw new Error(`您希望将buyCar设置为${val},但它是只读属性,不可更改!`);
            },
            configurable: false
        })
        this.createGoodsItemNoode();
        this.addEventListener();
        this.updateBuyCar();
    }
    get domList() {
        return {
            goodsContainer: document.querySelector('.goods-list'),
            footerCar: document.querySelector('.footer-car'),
            footerCarTip: document.querySelector('.footer-car-tip'),
            footerCarBadge: document.querySelector('.footer-car-badge'),
            footerCarTotal: document.querySelector('.footer-car-total'),
            footerPay: document.querySelector('.footer-pay'),
            footerPaySpan: document.querySelector('.footer-pay span'),
        }
    }
    get buyCarPositon() {
        const position = this.domList.footerCar.getBoundingClientRect();
        return { x: position.left + position.width / 2, y: position.top };
    }
    createGoodsItemNoode() {
        let goodsItemListHtmlStr = '';
        this.buyCar.uiGoodsList.forEach((item, index) => {
            goodsItemListHtmlStr += `
            <div class="goods-item">
            <img src="${item.goodsItem.pic}" alt="" class="goods-pic" />
            <div class="goods-info">
                <h2 class="goods-title">${item.goodsItem.title}</h2>
                <p class="goods-desc">${item.goodsItem.desc}</p>
                <p class="goods-sell">
                <span>月售 ${item.goodsItem.sellNumber}</span>
                <span>好评率${item.goodsItem.favorRate}%</span>
                </p>
                <div class="goods-confirm">
                <p class="goods-price">
                    <span class="goods-price-unit">￥</span>
                    <span>${item.goodsItem.price}</span>
                </p>
                <div class="goods-btns">
                    <i index="${index}" class="iconfont i-jianhao"></i>
                    <span>${item.chooseNum}</span>
                    <i index="${index}" class="iconfont i-jiajianzujianjiahao"></i>
                </div>
                </div>
            </div>
            </div>
            `
        })
        this.domList.goodsContainer.innerHTML = goodsItemListHtmlStr;
    }
    addEventListener() {
        this.domList.footerCar.addEventListener('animationend', () => { this.domList.footerCar.classList.remove('animate') })
        this.domList.goodsContainer.addEventListener('click', e => {
            const index = Number(e.target.getAttribute('index'));
            if(e.target.className == 'iconfont i-jiajianzujianjiahao') this.increase(index);
            if(e.target.className == 'iconfont i-jianhao') this.decrease(index);
        })
    }
    increase(index) {
        this.buyCar.increase(index);
        this.updateGoodsItem(index);
        this.updateBuyCar();
        this.addBtnJumpAnimation(index);
    }
    decrease(index) {
        this.buyCar.decrease(index);
        this.updateGoodsItem(index);
        this.updateBuyCar();
    }
    updateGoodsItem(index) {
        const goodsItemDom = this.domList.goodsContainer.children[index];
        if(this.buyCar.isChoose(index)) {
            goodsItemDom.classList.add('active');
            const chooseNumDom = goodsItemDom.querySelector('.goods-btns span');
            chooseNumDom.textContent = this.buyCar.uiGoodsList[index].chooseNum;
        }else goodsItemDom.classList.remove('active');
    }
    updateBuyCar() {
        const chooseNum = this.buyCar.chooseNum;
        const deliveryThresholdDifference = this.buyCar.deliveryThresholdDifference;
        this.domList.footerCarTotal.textContent = this.buyCar.totalPrice;
        this.domList.footerCarTip.textContent = `配送费￥${ this.buyCar.deliveryFee }`;
        
        if(chooseNum > 0) {
            this.domList.footerCar.classList.add('active');
            this.domList.footerCarBadge.textContent = chooseNum;
        }else this.domList.footerCar.classList.remove('active');

        if(deliveryThresholdDifference > 0) {
            this.domList.footerPay.classList.remove('active');
            this.domList.footerPaySpan.textContent = `还差￥${ deliveryThresholdDifference }元起送`;
        }else this.domList.footerPay.classList.add('active');
    }
    addBuyCarAnimation() {
        this.domList.footerCar.classList.add('animate');
    }
    addBtnJumpAnimation(index) {
        const position = this.domList.goodsContainer.children[index].querySelector('.i-jiajianzujianjiahao').getBoundingClientRect();
        const startPosition = { x: position.left + position.width / 2, y: position.top };

        const div = document.createElement('div');
        const i = document.createElement('i');
        document.body.appendChild(div);
        div.appendChild(i);
        div.className = 'add-to-car';
        i.className = 'iconfont i-jiajianzujianjiahao';
        div.style.transform = `translateX(${ startPosition.x }px)`;
        i.style.transform = `translateY(${ startPosition.y }px)`;
        div.style.transition = '0.5s linear';
        i.style.transition = '0.5s cubic-bezier(0.5, -0.5, 1, 1)';
        div.clientWidth; //强行立即渲染
        div.style.transform = `translateX(${ this.buyCarPositon.x }px)`;
        i.style.transform = `translateY(${ this.buyCarPositon.y }px)`;

        div.addEventListener('transitionend', () => {
            div.remove();
            this.addBuyCarAnimation();
        }, { once: true });
    }
}

// window.goodList = goodList;
// window.goods = new Goods(goodList[0]);
// window.buyCar = new BuyCar();
window.ui = new Ui();